package com.example.mybatisdemo.config;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.keygen.SelectKeyGenerator;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;

import java.util.Locale;
import java.util.Properties;

@Intercepts({
        @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class}),
        @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),
})
@Slf4j
@Component
public class DynamicDataSourceInterceptor implements Interceptor {


    // 正则匹配update等写语句
    private static final String SQL_REGEX = ".*insert\\u0020.*|.*delete\\u0020.*|.*update\\u0020.*";


    @Override
    public Object intercept(Invocation invocation) throws Throwable {

        String lookupKey = DynamicDataSourceHolder.master;
        Object[] args = invocation.getArgs();
        //mybatis statment 就是mapper xml文件中的select标签
        MappedStatement mappedStatements = (MappedStatement) args[0];
        BoundSql sql = mappedStatements.getSqlSource().getBoundSql(args[1]);
        String manualDBType = DynamicDataSourceHolder.getManualDBType();
        if(StringUtils.isNotBlank(manualDBType)){
            DynamicDataSourceHolder.setDBType(manualDBType);
        } else {
            DynamicDataSourceHolder.setDBType(lookupKey);
        }

        return invocation.proceed();
    }


    @Override
    public Object plugin(Object o) {
        if(o instanceof Executor) {
            return Plugin.wrap(o, this);
        } else {
            return o;
        }
    }


    @Override
    public void setProperties(Properties properties) {

    }

}
